package org.duncan.sjge;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import org.duncan.sjge.events.GameManager;
import org.duncan.sjge.events.RenderEvent;
import org.duncan.sjge.events.UpdateEvent;
import org.duncan.sjge.utils.Time;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.duncan.sjge.keyboard.Keyboard;

/**
 *
 * @author Duncan
 */
public class GameWindow extends JFrame {
    private boolean mGameRunning = false;
    private BufferStrategy mStrategy;
    private JPanel mCanvas;
    
    public GameWindow() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        mCanvas = new JPanel();
        setPreferredSize(new Dimension(1280, 720));
        setLayout(new BorderLayout());
        
        mCanvas.setBackground(Color.red);
        
        add(BorderLayout.CENTER, mCanvas);
        mCanvas.setIgnoreRepaint(true);
        addKeyListener(Keyboard.instance().createListener());
        
        pack();
        setResizable(false);
        setVisible(true);
        
        createBufferStrategy(2);
        mStrategy = getBufferStrategy();
    }

    public void run() {
        mGameRunning = true;
        long lastTime = System.currentTimeMillis();
        
        while (mGameRunning) {
            // Handle time.
            long time  = System.currentTimeMillis();
            long delta = time - lastTime;
            lastTime   = time;
            
            // Create update event.
            final UpdateEvent updateEv = new UpdateEvent(
                    new Time.Milliseconds(time), 
                    new Time.Milliseconds(delta)
            );
            
            // Create render event.
            final Graphics2D g = (Graphics2D) mStrategy.getDrawGraphics();
            g.setColor(Color.black);
            g.fillRect(0, 0, 1280, 720);
            
            final RenderEvent renderEv = new RenderEvent(g);
            
            // Send events to entities.
            GameManager.instance().callCreate();
            GameManager.instance().callUpdate(updateEv);
            GameManager.instance().callRender(renderEv);
            GameManager.instance().callDestroy();
            
            // Dispose of graphics
            g.dispose();
            mStrategy.show();
        }
    }
}
